package com.pentalog.ginet;

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.pentalog.ginet.domain.Address;
import com.pentalog.ginet.domain.Employee;
import com.pentalog.ginet.domain.Student;

public class TestManageEmployee {
	private static SessionFactory factory;

	public static void main(String[] args) {
		try {
			factory = new Configuration().configure().buildSessionFactory();
		} catch (Throwable ex) {
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
		}
		TestManageEmployee ME = new TestManageEmployee();
//		ME.namedQuery();
//		ME.scalarQuery1();
		/* Add few employee records in database */
		/*Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
		Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
		Integer empID3 = ME.addEmployee("John", "Paul", 10000);*/
//		for(int i = 1; i <= 5; i++) {
//			ME.count();
//		}
		/* List down all the employees */
		ME.testEmployeesLazy();

		/* Update employee's records */
		// ME.updateEmployee(empID1, 5000);

		/* Delete an employee from the database */
		// ME.deleteEmployee(empID2);

		/* List down new list of the employees */
		// ME.listEmployees();
	}
	public void namedQuery() {
		Session session = factory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Query query = session.getNamedQuery("find.employee.by.first.name");
			query.setString("firstName", "Zara");
			List employees = query.list();
			for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
				Employee employee = (Employee) iterator.next();
				System.out.print(employee.getId() + "\t|First Name:\t|"
						+ employee.getFirstName());
				System.out.print("\t|Last Name:\t|" + employee.getLastName());
				System.out.println("\t|Salary:\t|" + employee.getSalary());
			}
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	//and in navetive query
	public void scalarQuery() {
		Session session = factory.openSession();
		Transaction tx = null;
		Integer employeeID = null;
		try {
			tx = session.beginTransaction();
//			TimerGinet time = new TimerGinet("TestManageEmployee");
			String sql = "FROM Employee, Student";
			Query query = session.createQuery(sql);
			
			List iter = query.list();
			for (Iterator iterator = iter.iterator(); iterator.hasNext();) {
	            Object[] tuple = (Object[]) iterator.next();
	            System.out.print(((Employee)tuple[0]).getFirstName());
	            System.out.println(((Student)tuple[1]).getStudentName());
	        }
			tx.commit();
//			time.done();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	public void scalarQuery1() {
		Session session = factory.openSession();
		Transaction tx = null;
		Integer employeeID = null;
		try {
			tx = session.beginTransaction();
//			TimerGinet time = new TimerGinet("TestManageEmployee");
			String sql = "select e.firstName,e.lastName from Employee e";
			Query query = session.createQuery(sql);
			
			List iter = query.list();
			System.out.println("------------------------------------------------");
			System.out.println("firstName\t|\ttlastName");
			System.out.println("------------------------------------------------");
			for (Iterator iterator = iter.iterator(); iterator.hasNext();) {
	            Object[] tuple = (Object[]) iterator.next();
	            System.out.print("\t"+((String)tuple[0])+"\t|\t");
	            System.out.println(((String)tuple[1]));
	        }
			tx.commit();
//			time.done();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	/* Method to CREATE an employee in the database */
	public Integer addEmployee(String fname, String lname, int salary) {
		Session session = factory.openSession();
		Transaction tx = null;
		Integer employeeID = null;
		try {
			tx = session.beginTransaction();
			Employee employee = new Employee(fname, lname, salary,null);
			employeeID = (Integer) session.save(employee);
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return employeeID;
	}

	public void testEmployeesLazy() {
		Session session = factory.openSession();
		Transaction tx = null;
		Employee emp = null;
		try {
			tx = session.beginTransaction();
			emp = (Employee)session.createQuery("FROM Employee e where e.id = 1").uniqueResult();
			tx.commit();
			
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
//			System.out.println(emp.getAddress().getStreet());
		}
	}
	/* Method to READ all the employees */
	public void listEmployees() {
		Session session = factory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			List employees = session.createQuery("FROM Employee").list();
			for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
				Employee employee = (Employee) iterator.next();
				System.out.print("First Name: " + employee.getFirstName()); 
	            System.out.print("  Last Name: " + employee.getLastName()); 
	            System.out.println("  Salary: " + employee.getSalary());
	            Address add = employee.getAddress();
	            System.out.println("Address ");
	            System.out.println("\tStreet: " +  add.getStreet());
	            System.out.println("\tCity: " + add.getCity());
	            System.out.println("\tState: " + add.getState());
	            System.out.println("\tZipcode: " + add.getZipcode());
			}
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

	/* Method to UPDATE salary for an employee */
	public void updateEmployee(Integer EmployeeID, int salary) {
		Session session = factory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Employee employee = (Employee) session.get(Employee.class,
					EmployeeID);
			employee.setSalary(salary);
			session.update(employee);
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

	/* Method to DELETE an employee from the records */
	public void deleteEmployee(Integer EmployeeID) {
		Session session = factory.openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Employee employee = (Employee) session.get(Employee.class,
					EmployeeID);
			session.delete(employee);
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
}
